package com.bootnetty.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by stevenfenCai on 2019-11-12.
 */
public class StringUtils {

    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    /**
     *十六进制字符串转换为byte数组
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase().replace(" ", "");
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    /**
     * 转换为日期时间
     * @param ms
     * @return
     */
    public static Date transForDate(Long ms){
        if(ms==null){
            ms=(long)0;
        }
        long msl=(long)ms*1000;
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date temp=null;
        if(ms!=null){
            try {
                String str=sdf.format(msl);
                temp=sdf.parse(str);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return temp;
    }

    /**
     * byte数组转换成十六进制字符串
     * @param b
     * @return
     */
    public static String conver2HexStr(byte [] b)
    {
        StringBuffer result = new StringBuffer();
        for(int i = 0;i<b.length;i++)
        {
            result.append(Long.toString(b[i] & 0xff, 2)+",");
        }
        return result.toString().substring(0, result.length()-1);
    }

    /**
     * 整数转换为二进制字符串
     * @param x
     * @return
     */
    public static String toBinaryString(int x){
        String result = Integer.toBinaryString(x);
        int len = 4 - result.length();
        for(int i=0;i<len;i++){
            result = "0"+result;
        }
        return result;
    }

    /**
     * 高低位翻转
     * @param str
     * @return
     */
    public static String reverse(String str){
        int len = str.length()/2;
        String one = str.substring(0,len);
        String two = str.substring(len,str.length());
        return two + one;
    }

    /**
     * byte
     *
     * @param bytes byte数组转换为16进制字符串
     * @return
     */
    public static String bytesToHexFun2(byte[] bytes, int len) {
        // 一个byte为8位，可用两个十六进制位标识
        char[] buf = new char[bytes.length * 2];
        int index = 0;
        for (byte b : bytes) { // 利用位运算进行转换，可以看作方法一的变种
            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
            buf[index++] = HEX_CHAR[b & 0xf];
        }
        return new String(buf).substring(0, len * 2);
    }

    /**
     * 计算CRC16算法
     *
     * @param data
     * @return
     */
    public static String getCrc(byte[] data) {
        int len = data.length;

        //预置 1 个 16 位的寄存器为十六进制FFFF, 称此寄存器为 CRC寄存器。
        int crc = 0xFFFF;
        int i, j;
        for (i = 0; i < len; i++) {
            //把第一个 8 位二进制数据 与 16 位的 CRC寄存器的低 8 位相异或, 把结果放于 CRC寄存器
            crc = ((crc & 0xFF00) | (crc & 0x00FF) ^ (data[i] & 0xFF));
            for (j = 0; j < 8; j++) {
                //把 CRC 寄存器的内容右移一位( 朝低位)用 0 填补最高位, 并检查右移后的移出位
                if ((crc & 0x0001) > 0) {
                    //如果移出位为 1, CRC寄存器与多项式A001进行异或
                    crc = crc >> 1;
                    crc = crc ^ 0xA001;
                } else
                    //如果移出位为 0,再次右移一位
                    crc = crc >> 1;
            }
        }

        //高低位互换
        String temp = numToHex16(crc);
        temp = temp.substring(2, 4) + temp.substring(0, 2);
        return temp;
    }

    //需要使用2字节表示b
    public static String numToHex16(int b) {
        return String.format("%04x", b);
    }

    /**
     * 函数名称：hexStr2Byte</br> 功能描述：String 转数组
     *
     * @param hex
     * @return 修改日志:</br>
     * <table>
     * <tr>
     * <th>版本</th>
     * <th>日期</th>
     * <th>作者</th>
     * <th>描述</th>
     * <tr>
     * <td>0.1</td>
     * <td>2014-7-16</td>
     * <td>ZhaoQing</td>
     * <td>初始创建</td>
     * </table>
     * @author ZhaoQing
     */
    public static byte[] hexStr2Byte(String hex) {
        if(hex == null || hex.trim().equals("")) {
            return new byte[0];
        }

        byte[] bytes = new byte[hex.length() / 2];
        for(int i = 0; i < hex.length() / 2; i++) {
            String subStr = hex.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }

        return bytes;
    }

    /**
     * CRC验证
     *
     * @param info
     * @return
     */
    public static boolean verificate(String info) {
        String crc = info.substring(4, 8);
        System.out.println(crc);
        System.out.println(getCrc(hexStr2Byte(info.substring(8, info.length()))));
        if (getCrc(hexStr2Byte(info.substring(8, info.length()))).toUpperCase().equals(crc)) {
            return true;
        }
        return false;
    }

    /**
     * 将字节数组转换成16进制字符串
     *
     * @param array   需要转换的字符串
     * @param toPrint 是否为了打印输出，如果为true则会每4自己添加一个空格
     * @return 转换完成的字符串
     */
    public static String byteArrayToHexString(byte[] array, boolean toPrint) {
        if (array == null) {
            return "null";
        }
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < array.length; i++) {
            sb.append(byteToHex(array[i]));
            if (toPrint && (i + 1) % 4 == 0) {
                sb.append("");
            }
        }
        return sb.toString();
    }

    /**
     * 函数名称：byteToHex</br> 功能描述：byte转16进制
     *
     * @param b
     * @return 修改日志:</br>
     * <table>
     * <tr>
     * <th>版本</th>
     * <th>日期</th>
     * <th>作者</th>
     * <th>描述</th>
     * <tr>
     * <td>0.1</td>
     * <td>2014-6-26</td>
     * <td>ZhaoQing</td>
     * <td>初始创建</td>
     * </table>
     * @author ZhaoQing
     */
    public static String byteToHex(byte b) {
        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;

        }
        return hex.toUpperCase(Locale.getDefault());

    }


    public static int StrtransInt(String value){

        Integer x = Integer.parseInt(value,16);
        return x;
    }
}
